## 13.6. Java

Java is a network-aware, object-oriented language developed by Sun Microsystems. Java has been causing a lot of excitement in the computing community as it strives to provide a secure language for running applets downloaded from World Wide Web sites. The idea is simple: allow web browsers to download Java applets, which run on the client's machine. The popular Netscape web browser (discussed in Chapter 16, "The World Wide Web and Electronic Mail" ) includes support for Java, and the Java Developer's Kit and other tools have been ported to Linux. But Java is not only suitable for those applets, in recent time, it has been used more and more as a general purpose programming language that offers fewer obstacles for beginners and that--because of its built-in networking libraries--is often used for programming client/server applications.

### 13.6.1. The Promise of Java, or Why You Might Want to Use Java

All this may not sound too exciting to you. There are lots of object-oriented programming languages, after all, and with Netscape plug-ins you can download executable programs from web servers and execute them on your local machine.

But Java is more. One of its most exciting aspects is platform independence. That means that you can write and compile your Java program and then deploy it on almost every machine, whether it is a lowly 386 running Linux, a powerful Pentium II running the latest bloatware from Microsoft, or an IBM mainframe. Sun Microsystems calls this "Write Once, Run Anywhere." Unfortunately, real life is not as simple as design goals. There are tiny, but frustrating, differences that make a program work on one platform and fail on another. With the advent of the new GUI library Swing in Java 2.0, a large step has been made to remedy this.

This neat feature of compiling code once and then being able to run it on another machine is made possible by the Java Virtual Machine (JVM). The Java compiler does not generate object code for a particular CPU and operating system like `gcc` does, it generates code for the Java Virtual Machine. This machine does not exist anywhere in hardware (yet), but is instead a specification. This specification says which so-called opcodes the machine understands and what the machine does when it encounters them in the object file. The program is distributed in binary form containing so-called byte codes that follow the Java Virtual Machine specification.

Now all you need is a program that implements the Java Virtual Machine on your particular computer and operating system. These are available nowadays for just about any platform--no vendor can dare not provide a Java Virtual Machine for its hardware or operating system. This program is also called the Java interpreter, because it interprets the opcodes compiled for the Java Virtual Machine and translates them into code for the native machine.

This distinction, which makes Java both a compiled and an interpreted language, makes it possible for you to write and compile your Java program and distribute it to someone else, and no matter what hardware and operating system she has, she will be able to run your program as long as a Java interpreter is available for it.

Alas, Java's platform independence comes at a price. Because the object code is not object code of any currently existing hardware, it must pass through an extra layer of processing, meaning that programs written in Java typically run ten to twenty times slower than comparable programs written in, for example, C. While this does not matter for some cases, in other cases it is simply unacceptable. There are so-called Just-In-Time compilers available that first translate the object code for the Java Virtual Machine into native object code and then run this object code. When the same object code is run a second time, the precompiled native code can be used without any interpretation and thus runs faster. But the speed that can be achieved with this is still inferior to that of C programs. Sun Microsystems is working on a technology that is said to provide an execution speed "comparable to C programs," but whether this promise can be fulfilled remains to be seen.

Java also distinguishes between applications and applets. Applications are standalone programs that are run from the command line or your local desktop and behave like ordinary programs. Applets, on the other hand, are programs (usually smaller) that run inside your web browser. (To run these programs, the browser needs a Java interpreter inside.) When you browse a web site that contains a Java applet, the web server sends you the object code of the applet, and your browser executes it for you. This can be used for anything from simple animations to complete online banking systems.[50]

> [50]One of us does all his financial business with his bank via a Java applet that his bank provides when browsing a special area of their web server.

When reading about the Java applets, you might have thought, "And what happens if the applet contains mischievous code that spies my hard disk or even maybe deletes or corrupts files?" Of course, this would be possible if the Java designers had not designed a multistep countermeasure against such attacks: All Java applets run in a so-called sandbox, which allows them access only to certain resources. For example, Java applets can output text on your monitor, but they can't read data from your local filesystem or even write to it unless you explicitly allow them to. While this sandbox paradigm reduces the usefulness of applets, it increases the security of your data. With recent Java releases, you can determine how much security you need and thus have additional flexibility.

If you decide that Java is something for you, we would recommend that you get a copy of Thinking in Java by Bruce Eckel. It covers most of the things you need to know in the Java world and also teaches you general programming principles. Other Java titles that are well worth looking into include Exploring Java by Pat Niemeyer and Josh Peck and Core Java by Gary Cornell and Cay Horstmann.

### 13.6.2. Getting Java for Linux

Fortunately, there is a Linux port of the so-called JDK, the Java Developers Kit provided by Sun Microsystem for Solaris and Windows which serves as a reference implementation of Java. In the past, there was usually a gap between the appearance of a new JDK version for Solaris and Windows and the availability of the JDK for Linux. Sun Microsystems has now promised to work closely together with the developers doing the Linux port, so there is hope that future Linux versions will be available in a timely manner.

The "official" Java implementation JDK contains a compiler, an interpreter and several related tools. Other kits are also available for Linux, often in the form of Open Source software. We'll cover the JDK here, though, because that's the standard.

One more note: Most distributions already contain the JDK for Linux, so it might be easier for you to simply install a prepackaged one. However, the JDK is moving fast, and you might want to install a newer version than the one your distribution contains.

Your one stop for shopping for Java software for Linux is http://www.blackdown.org. Here, you will find documentation, news about the Linux ports, and links to the places where you can download a copy of the JDK for your machine.

After unpacking and installing the JDK according to the instructions, you have several new programs at your disposal. `javac` is the Java compiler, `java` is the interpreter, and `appletviewer` is a small GUI program that lets you run applets without using a full-blown web browser.

### 13.6.3. A Working Example of Java

The following program (which has been written for Java 1.1, but should also work with Java 1.2/2) is a complete Java program that can run as a stand-alone application as well as an applet. It is a small painting program that lets you scribble on a virtual canvas. It also utilizes some GUI elements like a push button and an option menu.

The part of Java that lets you use GUI elements like windows and menus is called the Abstract Window Toolkit (AWT). It, too, helps fulfill Java's promise of "Write once, run anywhere." Even though different operating systems like Linux, Windows, and the Macintosh have completely different windowing systems, you need to write your user interface code only once. The AWT then maps the platform-independent widgets to a native GUI library. Thus, your program will have the native look of the respective windowing systems, depending on the system you run it on.

The AWT has a number of drawbacks, such as the different look that the programs have on each platform (some people consider this an advantage, though, because the program looks like a native application), the speed, and the numerous bugs. With the recent advent of Java 2.0, AWT will be replaced by a new toolkit called Swing that is based on an internal layer of the AWT and implements all user interface elements in Java. Swing projects usually look very nice but are even slower.

Enough talk now. Here is the code for the little scribbling program:

>     import java.applet.*;
>     import java.awt.*;
>     import java.awt.event.*;
>     /** An applet that can also run as a standalone application */
>     public class StandaloneScribble extends Applet {
>       /**
>        * The main() method.  If this program is invoked as an application,
>        * this method will create the necessary window, add the applet to it,

>        * and call init(), below.  Note that Frame uses a PanelLayout by
>        * default.
>        */
>       public static void main(String[] args) {
>         Frame f = new Frame();                     // Create a window
>         Applet a = new StandaloneScribble();       // Create the applet panel
>         f.add(a, "Center");                        // Add applet to window
>         a.init();                                  // Initialize the applet
>         f.setSize(400, 400);                       // Set the size of the
>                                                    // window
>         f.show();                                  // Make the window visible
>         f.addWindowListener(new WindowAdapter() {  // Handle window close
>                                                    // requests
>           public void windowClosing(WindowEvent e) { System.exit(0); }
>         });
>       }
>       /**
>        * The init() method.  If the program is invoked as an applet, the
>        * browser allocates screen space for it and calls this method to set
>        * things up.
>        */
>       public void init() {
>         // Define, instantiate and register a MouseListener object
>         this.addMouseListener(new MouseAdapter() {
>           public void mousePressed(MouseEvent e) {
>             lastx = e.getX();
>             lasty = e.getY();
>           }
>         });
>         // Define, instantiate and register a MouseMotionListener object
>         this.addMouseMotionListener(new MouseMotionAdapter() {
>           public void mouseDragged(MouseEvent e) {
>             Graphics g = getGraphics();
>             int x = e.getX(), y = e.getY();
>             g.setColor(Color.black);
>             g.drawLine(lastx, lasty, x, y);
>             lastx = x; lasty = y;
>           }
>         });
>         // Create a clear button
>         Button b = new Button("Clear");
>         // Define, instantiate, and register a listener to handle button
>         // presses
>         b.addActionListener(new ActionListener() {
>           public void actionPerformed(ActionEvent e) {  // clear the scribble
>             Graphics g = getGraphics();
>             g.setColor(getBackground());
>             g.fillRect(0, 0, getSize().width, getSize().height);
>           }
>         });

>         // And add the button to the applet
>         this.add(b);
>       }
>       protected int lastx, lasty;  // Coordinates of last mouse click
>     }

Save this code in a file named StandaloneScribble.java. The name is important; it must be the same as the name of the class implemented in the file with .java attached. To compile this code, issue the following command:

>     $tigger javac StandaloneScribble.java

This can take a while. The Java compiler is not particularly fast, mainly because it is written in Java itself. When it is done, it will have created a file StandaloneScribble.class together with some more .class files which we won't talk about here.

Now you can run this program from the command-line. Simply issue the command:

>     $tigger java StandaloneScribble

If you have installed the JDK correctly, you should get a window to scribble in. Note that the argument passed to the Java command was `StandaloneScribble` without the .class extension. This is because, technically, the interpreter is not executing the file, but the class.

You can also run this program, in a web browser or in the `appletviewer` from the JDK. For this, you need a bit of HTML code. The following should be enough:

>     <APPLET code="StandaloneScribble.class" width=150 height=100>
>     </APPLET>

Save this code to a file and open it with either a web browser like Netscape Navigator or the `appletviewer`, and you'll see the program in the browser window.

To finish this section, let's go through some of the most interesting lines of the program: In the first three lines, other Java classes that come from the JDK are imported. This is roughly comparable to including header files in a C program although there is no linking step in Java. When the program is run, the Java interpreter needs to be able to find the imported classes. It does this by looking in the directories mentioned in the environment variable CLASSPATH that you should have set up according to the JDK documentation.

Lines 13 through 21 contain the `main()` method. When the program is run as a standalone application, this method is called by the interpreter to start the execution of the program. In this method, a window is set up which is then used for screen output.

Most of the remaining code is the method `init()`. It is called either from `main()` when run standalone or directly from the web browser when run as an applet. In the latter case, `main()` is not executed at all.

### 13.6.4. Executing Java Programs Like Ordinary Programs

Since version 2.0, the Linux kernel has a nice feature that allows it to execute a Java program without explicitly invoking the interpreter. In order to enable this feature, you need to recompile your kernel (see Chapter 7, "Upgrading Software and the Kernel" ) and turn on Java binary format support. When you have installed the new kernel and rebooted your machine, you can make your class file executable and just run it from the command line. The Linux kernel will call the Java interpreter for you in the background:

>     tigger$ chmod +x StandaloneScribble.class
>     tigger$ ./StandaloneScribble.class

Nice feature, isn't it? The big boys like IBM and Microsoft are still trying to get it working. In case it does not work for you, the most probable reason is that the Linux-Kernel cannot find the Java interpreter. Check the values of the two constants `_PATH_JAVA` and `_PATH_APPLET` in the file /usr/src/linux/fs/binfmt_java.c. If these do not reflect the location of your Java interpreter and `appletviewer`, move the interpreter and the `appletviewer` to one of the directories shown. Alternatively, you can change the binfmt_java.c file to include the proper directory, after which you have to recompile and install your kernel.

Copyright © 2001 O'Reilly & Associates. All rights reserved.